#include "gd32f4xx.h"
#include <stdio.h>
#include <string.h>

#include "bsp_w25q64.h"
#include "bsp_usart.h"
#include "fatfs/ff.h"

void w25q64_fs_test(void) {
    static FATFS fs;
    static FIL fil;
    static BYTE work[FF_MAX_SS];

    // 挂载并初始化
	FRESULT res = f_mount(&fs, "0:", 1);
	if (res == FR_NO_FILESYSTEM) {
        res = f_mkfs("0:", 0, work, sizeof(work));
        if (res) {
            printf("文件系统格式化失败.\r\n");
            return ;
        } else {
            printf("文件系统格式化成功.\r\n");

            res = f_mount(&fs, "0:", 1);
            if (res) {
		        printf("文件系统挂载失败.\r\n");
                return;
            }
        }
	} else if (res) {
        printf("文件系统挂载失败.\r\n");
        return;
    }

    // 打开文件
    printf("文件系统挂载成功.\r\n");
	res = f_open(&fil, "0:/a.txt", FA_OPEN_ALWAYS|FA_WRITE|FA_READ);
	if (res) {
		printf("打开文件失败.\r\n");
        goto error;
	}
    printf("打开文件成功.\r\n");
    
    // 写入数据
    static uint16_t test_write_buf[8192];
    for (int i = 0; i < 8192; i++) {
        test_write_buf[i] = i;
    }

    UINT bw = 0;
	f_write(&fil, (void *)test_write_buf, sizeof(test_write_buf), &bw);
    if (bw != sizeof(test_write_buf)) {
		printf("写文件失败!\r\n");
        goto error;
    }

    // 读取数据
	FSIZE_t size = f_size(&fil);
	printf("文件大小:%d Bytes.\r\n",size);
	f_lseek(&fil,0);

    static uint16_t test_read_buf[8192];
	f_read(&fil,(void *)test_read_buf, sizeof(test_read_buf), &bw);
    if (bw != sizeof(test_read_buf)) {
		printf("读文件失败!\r\n");
        goto error;
    }

    // 比较数据
    if (memcmp(test_read_buf, test_write_buf, sizeof(test_read_buf)) != 0) {
        printf("数据读写失败，内容不一致\r\n");
    }

    // 结束
    printf("读写测试通过\r\n");

    // 创建文件并写入数据
    static char path[32];      // 文件名路径
    for (int i = 0; i < 10; i++) {
        sprintf(path, "file_txt%d.txt", i);  // 创建文件名
        res = f_open(&fil, path, FA_CREATE_ALWAYS | FA_WRITE);  // 打开文件
        if (res != FR_OK) {
            printf("Failed to open %s for writing.\n", path);
            continue;
        }
        f_close(&fil);  // 关闭文件
    }

    // 删除创建的文件
    for (int i = 0; i < 10; i++) {
        sprintf(path, "file_txt%d.txt", i);  // 创建文件名
        res = f_unlink(path);  // 删除文件
        if (res != FR_OK) {
            printf("Failed to delete %s.\n", path);
        }
    }

    printf("文件创建与删除成功\r\n");

error:
	f_close(&fil);
	f_unmount("0:");
}

void sdcard_fs_test(void) {
    static FATFS fs;
    static FIL fil;


        // 挂载并初始化
    FRESULT res = f_mount(&fs, "1:", 1);
	if (res) {
        printf("文件系统挂载失败.\r\n");
        return;
    }

    // 打开文件
    printf("文件系统挂载成功.\r\n");
	res = f_open(&fil, "1:/a.bin", FA_OPEN_ALWAYS|FA_WRITE|FA_READ);
	if (res) {
		printf("打开文件失败.\r\n");
        goto error;
	}
    printf("打开文件成功.\r\n");
    
    // 写入数据
    static uint16_t test_write_buf[8192];
    for (int i = 0; i < 8192; i++) {
        test_write_buf[i] = i;
    }

    UINT bw = 0;
	f_write(&fil, (void *)test_write_buf, sizeof(test_write_buf), &bw);
    if (bw != sizeof(test_write_buf)) {
		printf("写文件失败!\r\n");
        goto error;
    }

    // 读取数据
	FSIZE_t size = f_size(&fil);
	printf("文件大小:%d Bytes.\r\n",size);
	f_lseek(&fil,0);

    static uint16_t test_read_buf[8192];
	f_read(&fil,(void *)test_read_buf, sizeof(test_read_buf), &bw);
    if (bw != sizeof(test_read_buf)) {
		printf("读文件失败!\r\n");
        goto error;
    }

    // 比较数据
    if (memcmp(test_read_buf, test_write_buf, sizeof(test_read_buf)) != 0) {
        printf("数据读写失败，内容不一致\r\n");
    }

    // 结束
    printf("读写测试通过\r\n");
	f_close(&fil);

    // 创建文件并写入数据
    static char path[32];      // 文件名路径
    for (int i = 0; i < 10; i++) {
        sprintf(path, "1:/file_txt%d.txt", i);  // 创建文件名
        res = f_open(&fil, path, FA_CREATE_ALWAYS | FA_WRITE);  // 打开文件
        if (res != FR_OK) {
            printf("Failed to open %s for writing.\n", path);
            continue;
        }
        printf("create file %s\n", path);
        f_close(&fil);  // 关闭文件
    }

    // 删除创建的文件
    for (int i = 0; i < 10; i++) {
        sprintf(path, "1:/file_txt%d.txt", i);  // 创建文件名
        res = f_unlink(path);  // 删除文件
        if (res != FR_OK) {
            printf("Failed to delete %s.\n", path);
        }
        printf("delete file %s\n", path);
    }

    printf("文件创建与删除成功\r\n");

error:
	f_unmount("1:");
}

void w25q64_test (void) {
    w25q64_init_config();
    W25Q64_erase_chip();
}

int main(void) {
    usart_gpio_config(115200);
    
    //w25q64_test();
    //w25q64_fs_test();
    sdcard_fs_test();
    while(1) {
    }
}
